package com.atguigu.gulimail.search.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author Guo 2022/11/18 15:56:08
 */
@Slf4j
public class ThreadTest {

    public static ExecutorService service = Executors.newFixedThreadPool(10);

    /**
     * 开启线程的方式，new Thread()，执行start()方法
     * new Thread(() -> System.out.println("lll")).start();
     *
     * 1）、继承 Thread -- 异步进行，先执行1、4，然后2、3在后台才开始执行
     *      1   log.info("main...start");
     *      2   Thread01 thread01 = new Thread01();
     *      3   thread01.start();
     *      4   log.info("main...end");
     * 2）、实现 Runnable 接口  --  异步进行
     *         log.info("main...start");
     *         Runnable01 runnable01 = new Runnable01();
     *         new Thread(runnable01).start();
     *         log.info("main...end");
     * 3）、实现 Callable 接口 + FutureTask （可以拿到返回结果，可以处理异常）  阻塞式
     *         log.info("main...start");
     *         FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
     *         new Thread(futureTask).start();
     *         Integer i;
     *         try {
     *             // 阻塞式等待整个线程执行完成，获取返回结果
     *             i = futureTask.get();
     *         } catch (InterruptedException | ExecutionException e) {
     *             throw new RuntimeException(e);
     *         }
     *         log.info("callable的返回值"+ i);
     *         log.info("main...end");
     * 4）、线程池  -- 给线程池提交任务
     * 4.1 直接创建线程，大并发请求进来，会导致资源的耗尽，最终没有更多的资源来处理更核心的功能。
     * 4.2 以上三种启动线程的方式在业务代码中都不用。 --> 【将所有的多线程异步任务都交给线程池来执行】
     * 4.3 创建线程池的方式
     *         // 当前系统池应只有一两个,每个异步任务，提交给线程池让他自己去执行
     *         ExecutorService service = Executors.newFixedThreadPool(10);
     *         service.execute(new Runnable01());  // 执行线程池 无返回值
     *         service.submit(new Runnable01());  // 执行线程池 有返回值
     *
     */

    public static void main(String[] args) {
        log.info("main...start");
        // 使用线程池创建线程
        service.execute(new Runnable01());
        log.info("main...end");

    }

    public static class Thread01 extends Thread {
        @Override
        public void run() {
            log.info("当前线程" + Thread.currentThread().getId());
            int i = 10 / 5;
            log.info("计算结果:" + i);
        }
    }

    public static class Runnable01 implements Runnable {
        @Override
        public void run() {
            log.info("当前线程" + Thread.currentThread().getId());
            int i = 10 / 5;
            log.info("计算结果:" + i);
        }
    }

    public static class Callable01 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            log.info("当前线程" + Thread.currentThread().getId());
            int i = 10 / 5;
            log.info("计算结果:" + i);
            return i;
        }
    }



}
